package com.hooya.fa.eu.biz.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.hooya.fa.eu.api.bo.SkuLastPriceBO;
import com.hooya.fa.eu.api.vo.PkVO;
import com.hooya.fa.eu.biz.dao.entity.Pk;
import com.hooya.fa.eu.biz.dao.entity.TempKcjlDaily;
import com.hooya.fa.eu.biz.dao.entity.WmsKc;
import com.hooya.fa.eu.biz.dao.mapper.MetaRelationMapper;
import com.hooya.fa.eu.biz.dao.mapper.PkMapper;
import com.hooya.fa.eu.biz.dao.mapper.TempKcjlDailyMapper;
import com.hooya.fa.eu.biz.dao.mapper.WmsKcMapper;
import com.hooya.fa.eu.biz.service.InventoryService;
import com.hooya.integrated.common.core.util.BeanCopyUtils;
import com.hooya.integrated.common.util.currency.CurrencyConvertUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 1
 * @Author : Zongz
 * @Copyright Copyright (c) 豪雅集团
 * @Create 2025/1/22
 * @Version 1.1.0
 */
@Slf4j
@DS("fa_eu")
@Service
@AllArgsConstructor
public class InventoryServiceImpl implements InventoryService {

    private final TempKcjlDailyMapper tempKcjlDailyMapper;

    private final WmsKcMapper wmsKcMapper;

    private final PkMapper pkMapper;

    private final MetaRelationMapper metaRelationMapper;

    @Override
    @Transactional
    public void evenUp(String date) {
        List<Pk> res = new LinkedList<>();
        LocalDateTime now = LocalDateTime.now();
        List<WmsKc> wmsKcList = wmsKcMapper.selectList(null);
        Map<String, List<WmsKc>> wmsMap = wmsKcList.stream()
                .collect(Collectors.groupingBy(WmsKc::getSku));
        List<TempKcjlDaily> kcList = tempKcjlDailyMapper.getListByDate(date);
        Map<String, List<TempKcjlDaily>> kcMap = kcList.stream()
                .collect(Collectors.groupingBy(TempKcjlDaily::getCpbh));
        List<SkuLastPriceBO> skuPrice = metaRelationMapper.getSkuLastPrice();
        Map<String, Double> priceMap = skuPrice.stream().collect(Collectors.toMap(SkuLastPriceBO::getSku, SkuLastPriceBO::getPrice));
        wmsMap.forEach((sku, vmsList) -> {
            Double price = priceMap.get(sku);
            List<TempKcjlDaily> list = kcMap.get(sku);
            if (CollectionUtils.isEmpty(list)) {
                //盘盈
                for (WmsKc realKc : vmsList) {
                    log.error("理论不存在：" + realKc);
                    String belongs = "COSTWAY-" + realKc.getCountry();
                    genPy(res, belongs, realKc, realKc.getNum(), "盘盈[指定costway]", now, price);
                }
                return;
            }
            for (WmsKc realKc : vmsList) {
                Integer num = realKc.getNum();
                List<TempKcjlDaily> dailyList = list.stream().filter(l -> l.getPlace().equals(realKc.getPlace()) && l.getSl() != 0)
                        .collect(Collectors.toList());
                if (CollectionUtils.isEmpty(dailyList)) {
                    //盘盈
                    String belongs = "COSTWAY-" + realKc.getCountry();
                    genPy(res, belongs, realKc, num, "盘盈[指定costway]", now, price);
                } else {
                    for (TempKcjlDaily daily : dailyList) {
                        int max = Math.max(num - daily.getSl(), 0);
                        if (max > 0) {
                            genPy(res, daily.getBelongs(), realKc, daily.getSl(), "", now, price);
                            num = num - daily.getSl();
                            kcList.stream().filter(l -> l.getId().equals(daily.getId())).forEach(l -> l.setSl(0));
                        } else {
                            //刚好扣完/不够扣
                            genPy(res, daily.getBelongs(), realKc, num, "", now, price);
                            if (!num.equals(daily.getSl())) {
                                int remainingNum = daily.getSl() - num;
                                kcList.stream().filter(l -> l.getId().equals(daily.getId())).forEach(l -> l.setSl(remainingNum));
                            } else {
                                kcList.stream().filter(l -> l.getId().equals(daily.getId())).forEach(l -> l.setSl(0));
                            }
                            num = 0;
                            break;
                        }
                    }
                    if (num > 0) {
                        String belongs = "COSTWAY-" + realKc.getCountry();
                        genPy(res, belongs, realKc, num, "盘盈[指定costway]", now, price);
                    }
                }
            }
        });
        List<TempKcjlDaily> lossList = kcList.stream().filter(l -> l.getSl() != 0).collect(Collectors.toList());
        res.addAll(BeanCopyUtils.copyListProperties(lossList, Pk::new, (s, t) -> {
            Double price = priceMap.get(s.getCpbh());
            t.setSku(s.getCpbh());
            t.setNum(Math.negateExact(s.getSl()));
            t.setPrice(CurrencyConvertUtil.convertFenFromYuanStandard(price));
            t.setType("盘亏");
            t.setCreateTime(now);
        }));
        res.forEach(l -> l.setDate(date));
//        List<List<Pk>> splitRes = DataMethod.splitData(res, 4000);
//        for (List<Pk> pkList : splitRes) {
//            pkMapper.insertBatchSomeColumn(pkList);
//        }
    }

    private void genPy(List<Pk> res, String belongs, WmsKc realKc, Integer num, String type, LocalDateTime now, Double price) {
        res.add(Pk.builder().sku(realKc.getSku()).place(realKc.getPlace()).belongs(belongs).createTime(now)
                .num(num).price(CurrencyConvertUtil.convertFenFromYuanStandard(price))
                .position(realKc.getPosition()).type(type).build());
    }

    @Override
    public List<PkVO> evenUpReport() {
        return BeanCopyUtils.copyListProperties(pkMapper.selectList(null), PkVO::new,
                (s, t) -> t.setPrice(CurrencyConvertUtil.convertYuanFromFenStandard(s.getPrice())));
    }
}
